package utils

import (
	"encoding/json"
	"fmt"
	"strings"
)

func ParseFilter(filter string) (map[string]any, error) {
	var filterMap map[string]any
	if err := json.Unmarshal([]byte(filter), &filterMap); err != nil {
		return nil, err
	}
	return filterMap, nil
}

func ReplaceKeys(originalMap map[string]any, keymap map[string]string) map[string]any {
	newMap := make(map[string]any)

	for key, value := range originalMap {
		if newKey, ok := keymap[key]; ok {
			newMap[newKey] = value
		} else {
			newMap[key] = value
		}
	}

	return newMap
}

func ParseRange(rangeStr string) (uint, uint, error) {
	// parse string like [0,9]
	var rangeSlice []uint
	if err := json.Unmarshal([]byte(rangeStr), &rangeSlice); err != nil {
		return 0, 0, err
	}
	return rangeSlice[0], rangeSlice[1], nil
}

func ParseSort(sort string) (string, string, error) {
	// parse string like ["id","asc"]
	var sortSlice []string
	if err := json.Unmarshal([]byte(sort), &sortSlice); err != nil {
		return "", "", err
	}
	return sortSlice[0], sortSlice[1], nil
}

func colsLike(cols []string, keyword string) (query string, values []interface{}) {
	// cols = ["name", "description"]
	// keyword = "hello"
	// return "name LIKE '%hello%' OR description LIKE '%hello%'"
	var orConditions []string
	var args []interface{}
	for _, col := range cols {
		orConditions = append(orConditions, col+" ILIKE ?")
		args = append(args, "%"+keyword+"%")
	}

	return fmt.Sprintf("(%s)", strings.Join(orConditions, " OR ")), args
}

func SearchQuery(q string, cols ...string) (query string, values []interface{}) {
	// q = "hello world"
	// cols = ["name", "description"]
	// return "name LIKE '%hello%' OR description LIKE '%hello%' OR name LIKE '%world%' OR description LIKE '%world%'"
	keywords := strings.Fields(q)

	var orConditions []string
	var args []interface{}
	for _, keyword := range keywords {
		or, as := colsLike(cols, keyword)
		orConditions = append(orConditions, or)
		args = append(args, as...)
	}

	return strings.Join(orConditions, " OR "), args
}
